package fons.model.query.fun;

import java.util.Map;

import com.google.common.collect.Maps;

public class Functions {
	private static final Map<String, Function> functions = createFunctions();
	
	public static <T> T reduceTo (Function fun, Class<T> clazz) {
		while (!clazz.isInstance(fun)) {
			Function prev = fun;
			fun = fun.apply();
			if (fun == prev) {
				try {
					return clazz.newInstance();
				} catch (InstantiationException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				}
			}
		}
		return clazz.cast(fun);
	}
	
	public static Function get(String name) {
		return functions.get(name); 
	}

	private static Map<String, Function> createFunctions() {
		Map<String, Function> functions = Maps.newHashMap();
		
		
		functions.put("more", new CompareFun(Comparator.MORE));
		functions.put("less", new CompareFun(Comparator.LESS));
		
		functions.put("count", new CountFun());
		functions.put("sort", new SortFun());
		
		functions.put("filter", new FilterFun());
		functions.put("first", new FirstFun());
		
		functions.put("div", new ArithmeticFun(Operator.DIVISION));
		functions.put("mul", new ArithmeticFun(Operator.MULTIPLICATION));
		functions.put("diff", new ArithmeticFun(Operator.DIFFERENCE));
		functions.put("sum", new ArithmeticFun(Operator.SUM));
		
		return functions;
	}
}
